﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Steve.UI.Controllers;
using System.Web.Mvc;
using Steve.UI.Models;
using System.Web;
using Steve.TestHelper;
using Moq;
using Steve.UI.Extensions;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Web.Security;
using Steve.UI.Administration.Models;
using Steve.UI.Administration.Controllers;

namespace Steve.UI.Tests
{
    [TestClass]
    public class SiteManagementController_Tests : ComposablePartTests
    {
        const string testId = "siteId";
        const string testAuthority = "www.google.com";

        protected override void InitializeGlobalTestData()
        {
            StubSiteExplorerRepository.AddSite(testId, testAuthority);
        }

        [TestMethod]
        public void Test_SiteDetail_Action_Existing()
        {
            var controller = this.ComposeController<SiteManagementControllerBase>();
            var result = controller.SiteDetail(testId);

            Assert.IsInstanceOfType(result, typeof(ViewResult));

            var viewResult = (ViewResult)result;

            Assert.AreEqual("ExistingSiteDetail", viewResult.ViewName);
            Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(ExistingSiteDetailModel));

            var model = (ExistingSiteDetailModel)viewResult.ViewData.Model;

            Assert.AreEqual(testId, model.SiteName);
            Assert.AreEqual(testAuthority, model.Authority);
        }

        [TestMethod]
        public void Test_SiteDetailPost_Action()
        {
            var controller = this.ComposeController<SiteManagementControllerBase>();
            var model = new ExistingSiteDetailModel()
            {
                Authority = "www.new.com",
                SiteName = testId
            };

            //TODO: how to handle validation???
            var userId = Guid.NewGuid();
            var u = new Mock<MembershipUser>();
            u.Setup(m => m.ProviderUserKey).Returns(userId);

            AccountMock.Setup(a => a.GetAuthenticatedUser()).Returns(u.Object);

            var result = controller.SiteDetailPost(model, testId);

            Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));

            //TODO: test result properties...

            var saved = StubSiteExplorerRepository._sites[testId];

            Assert.AreEqual(testId, saved.SiteName);
            Assert.AreEqual("www.new.com", saved.Authority);
            Assert.AreEqual(userId, saved.RevisionMembershipId);
        }

        [TestMethod]
        public void Test_SiteDetail_New_Action()
        {
            var controller = this.ComposeController<SiteManagementControllerBase>();
            var result = controller.SiteDetail(null);

            Assert.IsInstanceOfType(result, typeof(ViewResult));

            var viewResult = (ViewResult)result;

            Assert.AreEqual("NewSiteDetail", viewResult.ViewName);
            Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(NewSiteDetailModel));

            var model = (NewSiteDetailModel)viewResult.ViewData.Model;

            Assert.AreEqual(null, model.SiteName);
            Assert.AreEqual(null, model.Authority);
        }

        [TestMethod]
        public void Test_SiteList_Action()
        {
            var controller = this.ComposeController<SiteManagementControllerBase>();
            var result = controller.SiteList();

            Assert.IsInstanceOfType(result, typeof(ViewResult));

            var viewResult = (ViewResult)result;

            Assert.AreEqual("SiteList", viewResult.ViewName);
            Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(IEnumerable<Site>));

            var model = (IEnumerable<Site>)viewResult.ViewData.Model;

            Assert.AreEqual(1, model.Count());

            Assert.AreEqual(testId, model.First().SiteName);
            Assert.AreEqual(testAuthority, model.First().Authority);
        }

    }
}
